using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class ScreenHelper : MonoBehaviour
{
    private static ScreenHelper _instance;
    private static ScreenHelper Instance
    {
        get
        {
            if (!_instance)
            {
                _instance = GameObject.FindObjectOfType<ScreenHelper>();
                if (!_instance)
                {
                    GameObject go = new GameObject(nameof(ScreenHelper));
                    _instance = go.AddComponent<ScreenHelper>();
                }
            }
            return _instance;
        }
    }

    private static Canvas _canvas;
    private static Vector2 _screenSize;
    private static Vector2 _screenUISize;
    private static Camera _camera;
    private static float _screenRatio;

    public static void InitScreenSize(Camera camera)
    {
        if (!camera.orthographic)
        {
            Debug.LogError($"InitScreenSize 仅支持传入正交摄影机！");
            return;
        }
        _camera = camera;
        _screenRatio = camera.aspect;
        _screenSize.y = camera.orthographicSize * 2;
        _screenSize.x = _screenSize.y * camera.aspect;
    }

    public static void InitScreenUISize(Canvas canvas)
    {
        //这里先保存_canvas，后续第一次使用的时候再读取尺寸，否则在Awake里有时画布尺寸并没有准备好（已掉过坑）
        _canvas = canvas;
        _screenUISize = Vector2.zero;
    }

    /// <summary>
	/// 正交摄影机下的屏幕尺寸
	/// </summary>
	public static Vector2 screenSize
    {
        get
        {
            if (_screenSize == Vector2.zero)
            {
                Debug.LogError("请在最早时间调用 ScreenHelper.InitScreenSize(camera) 获得屏幕场景尺寸");
            }
            if (_screenRatio != _camera.aspect)
            {
                _screenRatio = _camera.aspect;
                _screenSize.y = _camera.orthographicSize * 2;
                _screenSize.x = _screenSize.y * _camera.aspect;
            }
            return _screenSize;
        }
    }

    /// <summary>
    /// UI全屏尺寸
    /// </summary>
    public static Vector2 screenUISize
    {
        get
        {
            if (!_canvas)
            {
                Debug.LogError("请在最早时间调用 ScreenHelper.InitScreenUISize(canvas) 获得屏幕UI尺寸");
            }
            if (_screenUISize == Vector2.zero)
            {
                _screenUISize = (_canvas.transform as RectTransform).sizeDelta;
            }
            return _screenUISize;
        }
    }

    /// <summary>
    /// 世界转换到UGUI坐标
    /// </summary>
    public static Vector2 WorldToUGUIPoint(Vector3 worldPos, Canvas canvas)
    {
        Camera camera = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera;
        Vector2 screenPos = RectTransformUtility.WorldToScreenPoint(camera, worldPos);
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, screenPos, camera, out Vector2 uiPos);
        return uiPos;
    }

    /// <summary>
    /// 屏幕转换到UGUI坐标
    /// </summary>
    public static Vector2 ScreenToUGUIPoint(Vector2 screenPos, Canvas canvas)
    {
        Camera camera = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, screenPos, camera, out Vector2 uiPos);
        return uiPos;
    }

    /// <summary>
    /// UGUI转换到屏幕坐标
    /// </summary>
    public static Vector3 UGUIToScreenPoint(Vector2 uiPos)
    {
        Vector3 p;
        p.x = Screen.width * (uiPos.x + screenUISize.x * 0.5f) / screenUISize.x;
        p.y = Screen.height * (uiPos.y + screenUISize.y * 0.5f) / screenUISize.y;
        p.z = 0;
        return p;
    }

    /// <summary>
    /// 仅当全场没有摄影机，Canvas也不用摄影机时适用
    /// </summary>
    public static Vector3 WorldToScreenPoint(Vector3 worldPos)
    {
        return new Vector3(worldPos.x / screenUISize.x, worldPos.y / screenUISize.y, 0);
    }

    /// <summary>
    /// UGUI子物体锚点坐标转Canvas根坐标
    /// </summary>
    public static Vector2 LocalToRootPos(Vector2 uiPos, Transform parent)
    {
        CanvasScaler _canvasScaler = parent.GetComponent<CanvasScaler>();
        while (!_canvasScaler)
        {
            uiPos += (parent as RectTransform).anchoredPosition;
            parent = parent.parent as RectTransform;
            _canvasScaler = parent.GetComponent<CanvasScaler>();
        }
        return uiPos;
    }

    /// <summary>
    /// 截取屏幕并返回
    /// </summary>
    public static void ScreenShot(Action<Texture2D> callback)
    {
        Instance.StartCoroutine(DoScreenShot(callback));
    }
    private static IEnumerator DoScreenShot(Action<Texture2D> callback)
    {
        yield return new WaitForEndOfFrame();
        Texture2D cutImage = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
        Rect rect = new Rect(0, 0, Screen.width, Screen.height);
        cutImage.ReadPixels(rect, 0, 0);
        cutImage.Apply();
        callback?.Invoke(cutImage);
    }
}
